单源最短路径(Bellman-Ford,Dijkstra)

单源最短路径算法

Bellman-Ford算法

      功能:求有向图中两点之间的最短距离

      条件:初始化d[v]的每个元素为无穷大,记录初始点到该点的距离,初始化π[v]的元素为nul,存储最短路径中该点的前驱节点

       算法描述:  从初始节点开始,选择以该节点出发的所有弧,做松弛操作,再选择新的已经未进行松弛操作的顶点,重复上述操作

      松弛操作:弧(u,v) 权值w[u,v],d[v],d[u]

              If(w[u,v]+d[u]<d[v])  //如果经节点u和弧(u,v)能够到v更近

                  d[v]=w[u,v]+d[u];//更新到v点的距离

                  π[v]=u;更新v点的前驱节点

伪代码:

       Realx(u,v,w)

           If(w[u,v]+d[u]<d[v])  //如果经节点u和弧(u,v)能够到v更近

                  d[v]=w[u,v]+d[u];//更新到v点的距离

                  π[v]=u;更新v点的前驱节点

Bellman-Ford(G,w,s)

        For(v∈V) do

               d[v]=maxnum;

                π[v]=null;

         d[s]=0;

        for(u=1:n)

            for(v=i+1:n)

                relax(u,v,w)

                  For(uv∈E)

                       If(d[v]>d[u]+w[u,v])

                           Return false;

Bellman-ford算法求单源最短路径代码

#include<iostream>

usingnamespace std;

int m =100000;

int d[10];

int  Pai[10];

void relax(inti, intj, intp[5][5]) {

    int c = p[i][j];

    if (d[i] + c < d[j])

    {

         d[j] = d[i] + c;

         Pai[j] = i;

    }

}

//运行时请释放上面的注释

intmainbell() {

    /*矩阵存储图中的信息

     假设条件图中有五个点,矩阵[i,j]表示节点i到节点j的弧长度

     map[]={

       0,5,m,m,10//m代表无穷大

       m,0,2,9,3

       7,m,0,6,m

       m,m,4,0,m

       m,2,m,1,0

      }

    */

    int n=5;//节点个数

    for (int i = 0; i < n;i++)

         d[i]= m;

    d[0]= 0;

    int map[5][5] = {

         {0,5,m,m,10},//m代表无穷大

         {m,0,2,9,3},

         {7,m,0,6,m},

         {m,m,4,0,m},

        {m,2,m,1,m }

    };

    for (int i = 0; i < n;i++)

         for (int j = 0; j < n;j++)

             relax(i,j, map);

    for (int i = 0; i < n-1;i++)

         printf("%d ", d[i]);

    printf("%d\n", d[n - 1]);

    return 0;

}

    

/*

Bellman-Ford算法是对每一个边都进行松弛操作,这样算法的一部分松弛操作会是多余的,

在其基础上,每次选择剩余节点中最小的距离节点进行松弛操作,如此改进便得到了dijkstra算法

此代码展示的是dijkstra算法,

    dijkstra概述:每次选剩余节点中距离最小的节点进行松弛操作,直至把所有节点选完

*/

Dijkstra算法:

         伪代码:

           For(v∈V) do

               d[v]=maxnum;

                π[v]=null;

         d[s]=0;

       S=null;Q=v;

        while(Q!=null)

               u=extrac-min(Q);

                s=s∪{u};

                for( v | (u,v)∈V)

                     relax(u,v,w)

dijstra算法求单源最短路径:

#include<iostream>

usingnamespace std;

int m =100000;

int d[10];

intflag[10];

int  Pai[10];

void relax(inti, intj, intp[5][5]) {

    int c = p[i][j];

    if (d[i] + c < d[j])

    {

         d[j] = d[i] + c;

         Pai[j] = i;

    }

}

int main(){

    /*矩阵存储图中的信息

    假设条件图中有五个点,矩阵[i,j]表示节点i到节点j的弧长度

    map[]={

    0,5,m,m,10//m代表无穷大

    m,0,2,9,3

    7,m,0,6,m

    m,m,4,0,m

    m,2,m,1,0

    }

    */

    int n = 5;//节点个数

    for (int i = 0; i < n;i++)

    {

         d[i]= m;

         flag[i]= 1;

    }

    d[0]= 0;

    int map[5][5] = {

         {0,5,m,m,10 },//m代表无穷大

    {m,0,2,9,3 },

    {7,m,0,6,m },

    {m,m,4,0,m },

    {m,2,m,1,m }

    };

    int sum = n;

    while (sum--)

    {

         int min_i, min=m;

         for (int h = 0; h < n;h++)

             if (flag[h] == 1&& d[h] < min)

             {

                  min_i= h;

                  min= d[h];

             }

         for (int j = 0; j < n; j++)

             relax(min_i,j, map);

         flag[min_i]= 0;

    }

        

            

    for (int i = 0; i < n -1; i++)

         printf("%d ", d[i]);

    printf("%d\n", d[n - 1]);

    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值